package edu.buaa.act.rtree.str

import edu.buaa.act.IndexEntry

abstract class Node {
    val isLeaf: Boolean
    val bound: Bound
    def compareTo(o:Node, dimIndex:Int): Boolean = this.bound.compareTo(o.bound, dimIndex)
}

class LeafNode(data: Array[IndexEntry], dataBlockCapacity:Int) extends Node {
    val childData: Array[IndexEntry] = data

    private def calcBound(data: Array[IndexEntry]): Bound = {
        val minEntityId = data.minBy(i => i.entityId).entityId
        val maxEntityId = data.maxBy(i => i.entityId).entityId
        val minStart = data.minBy(i => i.start).start
        val maxStart = data.maxBy(i => i.start).start
        val minEnd = data.minBy(i => i.end).end
        val maxEnd = data.maxBy(i => i.end).end
        val minVal = data.minBy(i => i.value).value
        val maxVal = data.maxBy(i => i.value).value
        new Bound((minEntityId, minStart, minEnd, minVal), (maxEntityId, maxStart, maxEnd, maxVal))
    }

    override val bound: Bound = calcBound(data)
    override val isLeaf: Boolean = true
}

class IndexNode(data: Array[Node], dataBlockCapacity:Int) extends Node{
    val childNode: Array[Node] = data
    override val bound: Bound = calcBound(data)

    private def calcBound(data: Array[Node]): Bound = {
        val minEntityId = data.minBy(i => i.bound.min).bound.min._1
        val maxEntityId = data.maxBy(i => i.bound.max).bound.max._1
        val minStart = data.minBy(i => i.bound.min(1)).bound.min._2
        val maxStart = data.maxBy(i => i.bound.max(1)).bound.max._2
        val minEnd = data.minBy(i => i.bound.min(2)).bound.min._3
        val maxEnd = data.maxBy(i => i.bound.max(2)).bound.max._3
        val minVal = data.minBy(i => i.bound.min(3)).bound.min._4
        val maxVal = data.maxBy(i => i.bound.max(3)).bound.max._4
        new Bound((minEntityId, minStart, minEnd, minVal), (maxEntityId, maxStart, maxEnd, maxVal))
    }

    override val isLeaf: Boolean = false
}
